﻿using Autofac;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Module = Autofac.Module;

namespace SD.App.Desktop
{
    /// <summary>
    /// Autofac 自动注册模块（按生命周期标记接口批量注册）
    /// 规则：实现 ISingletonLifetime → 单例；IScopedLifetime → 作用域；ITransientLifetime → 瞬时
    /// </summary>
    public class AutofacAutoRegisterModule : Module
    {         
        protected override void Load(ContainerBuilder builder)
        {
            // 1. 获取当前程序集（可根据需要扩展为多程序集扫描）
            Assembly currentAssembly = Assembly.GetExecutingAssembly();
            Log.Information($"Autofac 自动注册：扫描程序集 {currentAssembly.FullName}");

            // 2. 扫描所有实现了 ILifetimeMarker 的非抽象类（排除接口、抽象类、泛型定义）
            var lifetimeTypes = currentAssembly.GetTypes()
                .Where(t => !t.IsInterface && !t.IsAbstract && !t.IsGenericTypeDefinition)
                .Where(t => typeof(ILifetimeMarker).IsAssignableFrom(t))
                .ToList();

            Log.Debug($"发现 {lifetimeTypes.Count} 个需自动注册的服务");

            // 3. 按生命周期接口分类注册
            foreach (var serviceType in lifetimeTypes)
            {
                // 3.1 确定生命周期
                var lifetime = GetLifetime(serviceType);
                // 3.2 查找服务实现的所有接口（排除生命周期标记接口和 IDisposable）
                var interfaces = serviceType.GetInterfaces()
                    .Where(i => !typeof(ILifetimeMarker).IsAssignableFrom(i))
                    .Where(i => i != typeof(IDisposable))
                    .ToList();

                // 3.3 注册逻辑（优先按接口注册，无接口则注册自身）
                if (interfaces.Any())
                {
                    // 这种情况无法注册 ViewModel

                    // 普通接口（如 IUserService → UserService）
                    foreach (var @interface in interfaces)
                    {
                        RegisterWithLifetime(builder, @interface, serviceType, lifetime);
                    }
                }
            
                //else
                //{
                //    // 无接口服务（直接注册自身，如 ViewModel）
                //    RegisterWithLifetime(builder, serviceType, serviceType, lifetime);
                //}

                // 无接口服务（直接注册自身，如 ViewModel）
                RegisterWithLifetime(builder, serviceType, serviceType, lifetime);
            }

            // 4. 额外：泛型服务注册（如 BaseRepository<,> → IRepository<,>）
            RegisterGenericServices(builder, currentAssembly);
        }

        /// <summary>
        /// 根据服务类型获取生命周期
        /// </summary>
        private Lifetime GetLifetime(Type serviceType)
        {
            if (typeof(ISingletonLifetime).IsAssignableFrom(serviceType))
                return Lifetime.Singleton;
            if (typeof(IScopedLifetime).IsAssignableFrom(serviceType))
                return Lifetime.Scoped;
            if (typeof(ITransientLifetime).IsAssignableFrom(serviceType))
                return Lifetime.Transient;

            // 默认：瞬时生命周期（防止未标记的服务漏注册）
            return Lifetime.Transient;
        }

        /// <summary>
        /// 按生命周期注册服务
        /// </summary>
        private void RegisterWithLifetime(ContainerBuilder builder, Type serviceInterface, Type serviceImpl, Lifetime lifetime)
        {
            var registrationBuilder = builder.RegisterType(serviceImpl).As(serviceInterface);

            // 根据生命周期配置
            switch (lifetime)
            {
                case Lifetime.Singleton:
                    registrationBuilder.SingleInstance();
                    break;
                case Lifetime.Scoped:
                    registrationBuilder.InstancePerLifetimeScope();
                    break;
                case Lifetime.Transient:
                    registrationBuilder.InstancePerDependency();
                    break;
            }

            // 打印注册日志（生产环境可关闭）
            Log.Debug($"已注册：{serviceInterface.Name} → {serviceImpl.Name}（生命周期：{lifetime}）");
        }

        /// <summary>
        /// 注册泛型服务（如 BaseRepository<,>）
        /// </summary>
        private void RegisterGenericServices(ContainerBuilder builder, Assembly assembly)
        {
            // 扫描泛型服务实现（如 BaseRepository<,>）
            var genericServiceTypes = assembly.GetTypes()
                .Where(t => !t.IsInterface && !t.IsAbstract)
                .Where(t => t.IsGenericTypeDefinition)
                .Where(t => typeof(ILifetimeMarker).IsAssignableFrom(t))
                .ToList();

            foreach (var genericImplType in genericServiceTypes)
            {
                // 查找对应的泛型接口（如 BaseRepository<,> 实现 IRepository<,>）
                var genericInterfaces = genericImplType.GetInterfaces()
                    .Where(i => i.IsGenericTypeDefinition)
                    .Where(i => !typeof(ILifetimeMarker).IsAssignableFrom(i))
                    .ToList();

                foreach (var genericInterface in genericInterfaces)
                {
                    // 注册泛型服务（如 IRepository<,> → BaseRepository<,>）
                    var lifetime = GetLifetime(genericImplType);
                    var registrationBuilder = builder.RegisterGeneric(genericImplType).As(genericInterface);

                    // 配置生命周期
                    switch (lifetime)
                    {
                        case Lifetime.Singleton:
                            registrationBuilder.SingleInstance();
                            break;
                        case Lifetime.Scoped:
                            registrationBuilder.InstancePerLifetimeScope();
                            break;
                        case Lifetime.Transient:
                            registrationBuilder.InstancePerDependency();
                            break;
                    }

                    Log.Debug($"已注册泛型服务：{genericInterface.Name} → {genericImplType.Name}（生命周期：{lifetime}）");
                }
            }
        }

        /// <summary>
        /// 生命周期枚举（内部使用）
        /// </summary>
        private enum Lifetime
        {
            Singleton,
            Scoped,
            Transient
        }

    }
}
